package cn.net.autocode.platform.providers;

import cn.net.autocode.dbManager.handler.PreparedStatementHandler;
import cn.net.autocode.platform.exception.PlatformQueryException;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import cn.net.autocode.dbManager.SqlWrapper;
import cn.net.autocode.dbManager.SqlWrapperBuilder;
import cn.net.autocode.platform.providers.service.SaveServ;
import cn.net.autocode.core.bean.ResultT;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("autocode/editProvider")
public class EditProviderCtrl extends ProviderCtrl{

    private final SaveServ saveServ;


    public EditProviderCtrl(SaveServ saveServ) {
        this.saveServ = saveServ;
    }


    @RequestMapping("{tableCode}")
    @Transactional
    public ResultT execute(@PathVariable("tableCode") String tableCode, @RequestBody JSONObject data){
        //第一步，合理性校验
        JSONObject table;
        try {
            table = this.tableMsg(tableCode);
        } catch (PlatformQueryException e) {
            throw new RuntimeException(e.getMessage());
        }
        String tableName = table.getString("tableName");

        //获取集合数据
        Map<String,String> keys = new HashMap<>();
        String dataListKey = null;
        String dataListColumn = null;
        Map<String,String> arrayKeys = new HashMap<>();

        for (Map.Entry<String, Object> entry : data.entrySet()) {
            String key = entry.getKey();
            String columnName = this.getColumnName(table.getString("id"),key);
            if(columnName==null){
                throw new RuntimeException(key+"没有对应的table列名");
            }
            Object value = entry.getValue();
            if(value instanceof ArrayList<?>){
                dataListKey = key;
                dataListColumn = columnName;
                arrayKeys.put(key,columnName);
            }else{
                keys.put(key,columnName);
            }
        }

        if(keys.isEmpty()){
            throw new RuntimeException("传递参数不符合要求");
        }

        if(arrayKeys.size() != 1){
            throw new RuntimeException("传递参数不符合要求");
        }

        //第二步，判定是否需要处理关联表
        JSONArray dataListArray = data.getJSONArray(dataListKey);

        SqlWrapperBuilder swb1 = new SqlWrapperBuilder(tableName);
        for(Map.Entry<String,String> entry:keys.entrySet()){
            swb1.eq(entry.getValue(),data.getString(entry.getKey()));
        }

        //查询tableName对应的子表信息
        List<String> childrenTables = dictDao.queryListValue("select t1.fk_table from ac_table_ref t1,ac_table t2 where t1.table_id=t2.id and t2.table_name=? ",String.class,tableName);

        if(dataListArray.isEmpty()){
            if(!childrenTables.isEmpty()){
                this.deleteChildrenData(swb1,tableName,childrenTables);
            }
            //空表数据，直接删除
            SqlWrapper deleteSqlWrap = swb1.deleteSqlWrapper();
            dao.executeUpdate(deleteSqlWrap.getSql(),deleteSqlWrap.getParams().toArray());
        }else{
            Object firstValue = dataListArray.get(0);
            if (firstValue instanceof Map) {
                //获取关联表字段
                String pkTableColumn = this.pkTableColumn(tableName,dataListColumn);
                if (pkTableColumn==null){
                    throw new RuntimeException("没有找到仅仅通过"+dataListColumn+"字段与"+tableName+"关联的父表信息！");
                }
                String pkField = PreparedStatementHandler.columnToProperty(pkTableColumn);
                //删除不存在的数据
                List<String> dataList = new ArrayList<>();
                for(int i=0;i<dataListArray.size();i++){
                    JSONObject json = dataListArray.getJSONObject(i);
                    if(json!=null){
                        if(json.containsKey(pkField)){
                            dataList.add(json.getString(pkField));
                        }else if(json.containsKey("id")){
                            dataList.add(json.getString("id"));
                        }
                    }
                }

                if(!dataList.isEmpty()){
                    swb1.notIn(dataListColumn,dataList);
                }
                if(!childrenTables.isEmpty()){
                    this.deleteChildrenData(swb1,tableName,childrenTables);
                }
                SqlWrapper deleteSqlWrap = swb1.deleteSqlWrapper();
                dao.executeUpdate(deleteSqlWrap.getSql(),deleteSqlWrap.getParams().toArray());

                if (!dataList.isEmpty()){
                    //查询已存在的数据
                    SqlWrapperBuilder swb2 = new SqlWrapperBuilder(tableName).selectColumn(dataListColumn);
                    for(Map.Entry<String,String> entry:keys.entrySet()){
                        swb2.eq(entry.getValue(),data.getString(entry.getKey()));
                    }
                    SqlWrapper sw2 = swb2.sqlWrapper();
                    List<String> existsData =  dao.queryListValue(sw2.getSql(),String.class,sw2.getParams().toArray());
                    dataList.removeAll(existsData);

                    //获取字段的默认值设置
                    JSONArray columnsMsg = providerServ.columnsMsg(table.getString("id"));
                    //设置自增字段
                    JSONArray rules = dictDao.queryJSONArray("select * from ac_table_rules where rule_type in (11,12) and table_id=?", table.getString("id"));

                    for(int i=0;i<dataListArray.size();i++){
                        JSONObject json = dataListArray.getJSONObject(i);
                        if(dataList.contains(json.getString(pkField))){
                            json.put(dataListKey,json.getString(pkField));
                            json.remove("id");
                            for(Map.Entry<String,String> entry:keys.entrySet()){
                                json.put(entry.getKey(),data.getString(entry.getKey()));
                            }
                            saveServ.save(json,tableName,columnsMsg,rules);
                        }
                    }
                }
            }else{
                //基本类型，直接处理，不需要查询关联表
                List<String> dataList = new ArrayList<>();
                for(int i=0;i<dataListArray.size();i++){
                    dataList.add(dataListArray.getString(i));
                }

                if(!dataList.isEmpty()){
                    swb1.notIn(dataListColumn,dataList);
                }

                if(!childrenTables.isEmpty()){
                    this.deleteChildrenData(swb1,tableName,childrenTables);
                }

                SqlWrapper deleteSqlWrap = swb1.deleteSqlWrapper();
                dao.executeUpdate(deleteSqlWrap.getSql(),deleteSqlWrap.getParams().toArray());

                if (!dataList.isEmpty()){
                    //查询已存在的数据
                    SqlWrapperBuilder swb2 = new SqlWrapperBuilder(tableName).selectColumn(dataListColumn);
                    for(Map.Entry<String,String> entry:keys.entrySet()){
                        swb2.eq(entry.getValue(),data.getString(entry.getKey()));
                    }
                    SqlWrapper sw2 = swb2.sqlWrapper();
                    List<String> existsData =  dao.queryListValue(sw2.getSql(),String.class,sw2.getParams().toArray());
                    dataList.removeAll(existsData);

                    //获取字段的默认值设置
                    JSONArray columnsMsg = providerServ.columnsMsg(table.getString("id"));
                    //设置自增字段
                    JSONArray rules = dictDao.queryJSONArray("select * from ac_table_rules where rule_type in (11,12) and table_id=?", table.getString("id"));

                    for(String arrayValue:dataList){
                        JSONObject json = new JSONObject();
                        for(Map.Entry<String,String> entry:keys.entrySet()){
                            json.put(entry.getKey(),data.getString(entry.getKey()));
                        }
                        json.put(dataListKey,arrayValue);
                        saveServ.save(json,tableName,columnsMsg,rules);
                    }

                }
            }
        }
        return ResultT.success();
    }

    private void deleteChildrenData(SqlWrapperBuilder swb,String tableName,List<String> childrenTables){
        SqlWrapper sqlWrapper = swb.sqlWrapper();
        JSONArray mainTableDatas = dao.queryJSONArray(sqlWrapper.getSql(),sqlWrapper.getParams().toArray());
        for(String childrenTable:childrenTables){
            Map<String,Object> refs = dictDao.queryMapVT("select t1.fk_field value,t1.pk_field text from ac_table_ref t1,ac_table t2 where t1.table_id=t2.id and t2.table_name=? and t1.fk_table=?",String.class,tableName,childrenTable);
            SqlWrapperBuilder deleteChildrenSwb = new SqlWrapperBuilder(childrenTable);
            for(int i=0;i<mainTableDatas.size();i++){
                JSONObject mainTableData = mainTableDatas.getJSONObject(i);
                for(Map.Entry<String,Object> entry:refs.entrySet()){
                    deleteChildrenSwb.eq(entry.getKey(),mainTableData.get(PreparedStatementHandler.columnToProperty(entry.getValue().toString())));
                }
                SqlWrapper deleteChildren = deleteChildrenSwb.deleteSqlWrapper();
                dao.executeUpdate(deleteChildren.getSql(),deleteChildren.getParams().toArray());
            }
        }
    }
}
